use std::{io, path::PathBuf, sync::{mpsc::{self, Sender}, Arc, Mutex}, thread, time::Duration};
use std::io::Write;
// use crate::off_thread_ext::OffThreadExt;

mod off_thread_ext;
mod shared_channel;

#[derive(Debug)]
#[warn(dead_code)]
struct Color {
    red: u8,
    green: u8,
    blue: u8,
    alpha: u8,
}


const fn mono_to_rgba(level: u8) -> Color {
    Color {
        red: level,
        green: level,
        blue: level,
        alpha: 255,
    }
}

static HOSTNAME: Mutex<String> = Mutex::new(String::new());

const WHITE: Color = mono_to_rgba(255);
const BLACK: Color = mono_to_rgba(0);

fn main() {
    println!("Hello, world!");
    let text = "   ponles    \n     giraffes\niguanas\nsquid".to_string();
    let v = text.lines().map(|s| s.trim()).collect::<Vec<&str>>();
    println!("{:?}", v);
    HOSTNAME.lock().unwrap().push_str("test");
    println!("{:?}", HOSTNAME.lock().unwrap());

    println!("color white {:?}", WHITE);
    println!("color black {:?}", BLACK);
    mutil_thread();
    sender_receive();
    // text.lines().map(|s| s.trim()).filter(|s| *s != "iguanas").for_each(|s| println!("{}", s));
    let sender = sender_receive2();
    sender.send("test3".to_string()).unwrap();
    //接收输入字符串
    loop {
        let mut input = String::new();
        print!("请输入发送的字符：");
        // std::io::stdout().write("简单教程 ".as_bytes()).unwrap();
        std::io::stdout().flush().unwrap();
        io::stdin().read_line(&mut input).unwrap();
        sender.send(input.clone()).unwrap();
        if input.trim() == "exit".to_string() {
            break;
        }
    }
}


fn mutil_thread() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];
    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }
    for handle in handles {
        handle.join().unwrap();
    }
    println!("Result: {}", *counter.lock().unwrap());
}

fn sender_receive(){
    let (tx, rx) = mpsc::channel();
    let child = thread::spawn(move || {
       loop {
              match rx.recv() {
                Ok(value) =>{
                   println!("2Received {}", value);
                   if value == "exit" {
                       break;
                   }
                },
                _ => {
                    println!("");
                    thread::sleep(Duration::from_secs(1));
                },
              }
       }
    });
    tx.send("test1").unwrap();
    tx.send("test2").unwrap();
    tx.send("exit").unwrap();
    child.join().unwrap();
}

fn sender_receive2() -> Sender<String> {
    let (tx, rx) = mpsc::channel();
    thread::spawn(move || {
       loop {
              match rx.try_recv() {
                Ok(value) =>{
                   println!("1Received {}", value);
                   if value == "exit" {
                       break;
                   }
                },
                _ => {
                    // println!("idle one second");
                    thread::sleep(Duration::from_secs(1));
                },
              }
       }
    });
    tx.send("test1".to_string()).unwrap();
    tx.send("test2".to_string()).unwrap();
    tx
}


fn _start_file_reader_thread(documents:Vec<PathBuf>) -> (mpsc::Receiver<String>, thread::JoinHandle<io::Result<()>>) {
    let (tx, rx) = mpsc::channel();
    let handle = thread::spawn(move || {
        for path in documents {
            let content = std::fs::read_to_string(&path)?;
            if tx.send(content).is_err() {
                break;
            }
        }
        Ok(())
    });
    (rx, handle)
}

// fn start_file_indexing_thread(texts:mpsc::Receiver<String>) -> (mpsc::Receiver<InMemoryIndex>, thread::JoinHandle<()>) {
//     let (tx, rx) = mpsc::channel();
//     let handle = thread::spawn(move || {
//         let mut index = InMemoryIndex::from_single_document(texts.recv().unwrap());
//         for text in texts {
//             index.add_document(text);
//         }
//         tx.send(index).unwrap();
//     });
//     (rx, handle)
// }